//
// Created by XiaoXiu on 2025/5/17.
//

#ifndef SNAKE_H
#define SNAKE_H
#include <stdint.h>
#include <uthash.h>
//数据结构
typedef enum {
  PACKET_TYPE_NONE,
  PACKET_TYPE_INIT,
  PACKET_TYPE_FRAME,
  PACKET_TYPE_MOVE,
  PACKET_TYPE_DIR,
  PACKET_TYPE_JOIN,
  PACKET_TYPE_EXIT,
  PACKET_TYPE_FOOD_CREATE,
  PACKET_TYPE_FOOD_EATEN,
  PACKET_TYPE_ESC,
  PACKET_TYPE_SYNC
} PacketType;
typedef enum {
  DIR_UP,
  DIR_DOWN,
  DIR_LEFT,
  DIR_RIGHT,
  DIR_NONE,
} Direction;
// 位置结构体
typedef struct {
  int x;
  int y;
} Point;
typedef struct {
  Point position;
} Food;
typedef struct {
  Point *body;
  int length;
  int capacity;
  Direction direction;
  Direction next_direction;
} Snake;
typedef struct {
  char playerId[64];
  char playerName[17];
  Snake snake;
  UT_hash_handle hh;
} Player;
extern Player *players;
// INIT 包 — 由服务端发送，初始化游戏信息
typedef struct {
  int gridSize;
  int cellSize;
  int tick;
  int index;
  int delay;
  int moveInterval;
  int maxPlayers;
  Player *me; // UUID，最大长度64字节足够
  Snake snake;
} PacketInit;
typedef struct {
  int playersCount;
  Food nowFood;
  Player **players;
  Player *me;
  uint64_t timestamp;
  int index;
  int tickCounter;
} PacketSync;
// 单位包框架中各帧结构（FRAME, EXIT, FOOD_CREATE, FOOD_EATEN）
typedef struct {
  int index;
  uint64_t timestamp;
  char playerId[64];
  char playerName[17];
  int nowPlayerCount;
  Direction direction; //有direction字段的包才用，没方向就为DIR_NONE
  Point point; //FOOD包使用point
  Snake snake;
  PacketType type; //FRAME/EXIT/FOOD_CREATE/FOOD_EATEN
} PacketFrameItem;
// 服务端除了 INIT 外的包都是“帧包框架”，里面带多个帧单元
typedef struct {
  int index;
  uint64_t timestamp;
  int frameCount;
  PacketFrameItem *frames; // 动态数组
} PacketFrame;
// 客户端发送包（DIR/ESC/NONE）结构体
typedef struct {
  int index;
  uint64_t timestamp;
  char playerId[64];
  char playerName[17];
  Direction direction;
  PacketType type;
} PacketClientSend;
// 总包结构，包含所有包类型的联合体
typedef struct {
  PacketType type;
  union {
    PacketSync sync;
    PacketInit init; // type == PACKET_TYPE_INIT
    PacketFrame frame; // 服务端的多帧包框架（除了INIT）
    PacketClientSend clientSend; // 客户端发送包
  };
} Packet;

void free_player(Player *player);
void snake_free_packet(Packet *packet);
#endif //SNAKE_H
